﻿/*********************************************************************************
**                                                                              **
**  Copyright (C) 2024 LiLong                                                   **
**  This file is part of GnssLogs.                                              **
**                                                                              **
**  GnssLogs is free software: you can redistribute it and/or modify            **
**  it under the terms of the GNU Lesser General Public License as published by **
**  the Free Software Foundation, either version 3 of the License, or           **
**  (at your option) any later version.                                         **
**                                                                              **
**  GnssLogs is distributed in the hope that it will be useful,                 **
**  but WITHOUT ANY WARRANTY; without even the implied warranty of              **
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               **
**  GNU Lesser General Public License for more details.                         **
**                                                                              **
**  You should have received a copy of the GNU Lesser General Public License    **
**  along with GnssLogs.  If not, see <https://www.gnu.org/licenses/>.          **
**********************************************************************************/
#pragma once

#include "../AUTHCODES.h"
#include "LogHeaderDecoder.h"

namespace GnssLogs
{
namespace AUTHCODESDecoder
{
using Sync   = TAO_PEGTL_STRING("#AUTHCODESA");
using Header = LogHeaderDecoder::SyncExpression<Sync>;
// clang-format off
struct Status : ascii::identifier {};
struct NumberOfAuthCodes : star<digit> {};
struct AuthCodeTypeRule : ascii::identifier {};
struct Valid : Bool {};
struct AuthCodeString : StringLiteral {};
// clang-format on
using AuthCode   = seq<Split, AuthCodeTypeRule, Split, Valid, Split, AuthCodeString>;
using Expression = seq<Header, Status, Split, NumberOfAuthCodes, star<AuthCode>, one<'*'>, CRC32, Tail>;

template<typename T>
struct Action
{
};

template<>
struct Action<Header> : LogHeaderDecoder::LogHeaderHelperNoSetValue
{
};

template<>
struct Action<Status> : EnumHelper<Action<Status>, SignatureStatus>
{
    static void setValue(AUTHCODES::Data& data, SignatureStatus value) { data.status = value; }
};

template<>
struct Action<NumberOfAuthCodes> : IntHelper<Action<NumberOfAuthCodes>, uint32_t>
{
    static void setValue(AUTHCODES::Data& data, uint32_t value) { data.numberOfAuthCodes = value; }
};

template<>
struct Action<AuthCodeTypeRule> : EnumHelper<Action<AuthCodeTypeRule>, AuthCodeType>
{
    static void setValue(AUTHCODES::Data& data, AuthCodeType value)
    {
        data.authCodes.emplace_back(AUTHCODES::Data::AuthCode {});
        data.authCodes.back().authCodeType = value;
    }
};

template<>
struct Action<Valid> : BoolHelper<Action<Valid>>
{
    static void setValue(AUTHCODES::Data& data, bool value) { data.authCodes.back().valid = value; }
};

template<>
struct Action<AuthCodeString> : StringHelper<Action<AuthCodeString>>
{
    static void setValue(AUTHCODES::Data& data, const std::string& value) { data.authCodes.back().authCodeString = value; }
};

template<>
struct Action<CRC32> : CRC32Helper<Action<CRC32>>
{
    static void setValue(AUTHCODES::Data& data, uint32_t value) { data.crc32 = value; }
};
} // namespace AUTHCODESDecoder
} // namespace GnssLogs